#!/usr/bin/perl

######################################################################
package Swignition::uF::RelTag;
######################################################################

use Swignition::GenericParser::Utils;
use Swignition::MagicString;
use Swignition::uF;
use XML::LibXML qw(:all);
use strict;

sub consume
{
	my $page   = shift;

	unless ( $page->{Profiles}->{'http://purl.org/uF/rel-tag/1.0/'}
	||       $page->{Profiles}->{'http://purl.org/uF/rel-tag/class'}
	||       $page->{Profiles}->{'http://purl.org/uF/hAtom/0.1/'}
	||       $page->{Profiles}->{'http://purl.org/uF/hCalendar/1.0/'}
	||       $page->{Profiles}->{'http://purl.org/uF/hCalendar/1.1/'}
	||       $page->{Profiles}->{'http://purl.org/uF/hCard/1.0/'}
	||       $page->{Profiles}->{'http://purl.org/uF/2008/03/'}
	||      !$page->{options}->{uf_strict_profiles})
	{
		return;
	}

	$page->{uF}->{Tag} = [ parse_all($page) ];
	foreach my $tag (@{ $page->{uF}->{Tag} })
	{
		$page->mergeSubject( $tag->rdf_subject );
		my $val = Swignition::RDFModel::Value->new($tag->uri, 1);
		my $url = $page->uri;
		$page->{RDF}->{$url}->addVal('http://www.holygoat.co.uk/owl/redwood/0.1/tags/taggedWithTag', $val);
	}

	if (defined $page->{uF}->{Tag}->[0])
		{ $page->mergeNS( $page->{uF}->{Tag}->[0] ); }
}


sub parse_all
{
	my $page   = shift;
	my $within = shift || $page->{DOM};
	my @rv;

	my @nodes = searchRel('tag', $within);	
	foreach my $t (@nodes)
	{
		next unless ($t->tagName =~ /^ (a|area) $/ix);
		my $t_parsed = parse($page, $t);
		push @rv, $t_parsed;
	}

	if ($page->{Profiles}->{'http://purl.org/uF/rel-tag/class'})
	{
		my @nodes = searchClass('tag', $within);	
		foreach my $t (@nodes)
		{
			next unless ($t->tagName =~ /^ (a|area) $/ix);
			next if ($t->getAttribute('rel') =~ /\b tag \b/ix);
			my $t_parsed = parse_class($page, $t);
			push @rv, $t_parsed;
		}
	}
	
	return @rv;
} #/sub parse_all


sub uri
{
	my $this = shift;
	my $all  = shift;
	my @rv;
	
	push @rv, $this->{href};

	return $rv[0] unless (defined $all);
	while ($all) { shift @rv; $all--; }
	return @rv;
} #/sub uri


sub uri_tagging
{
	my $this = shift;
	my $all  = shift;
	my @rv;
	
	if (length $this->{_id})
	{
		push @rv, $this->{_page}->uri.'#'.$this->{_id};
	}
	if (lc($this->{_dom}->tagName) eq 'body')
	{
		push @rv, $this->{_page}->uri;
	}
	push @rv, Swignition::GenericParser::Utils::BNodeURI($this->{_dom}, 'Tagging')
		unless (@rv);
	
	return $rv[0] unless (defined $all);
	while ($all) { shift @rv; $all--; }
	return @rv;
} #/sub uri



sub metadata_ns
{
	my $this = shift;
	return { 
		'awol' => { nsurl=>'http://bblfish.net/work/atom-owl/2006-06-06/#',   title=>'Atom OWL' },
		'tag'  => { nsurl=>'http://www.holygoat.co.uk/owl/redwood/0.1/tags/', title=>'Tagging vocab' }
	};
} #/sub namespace


sub rdf_subject
{
	my $this    = shift;

	# Create RDF subject
	my $subject = Swignition::RDFModel::Subject->new($this->uri);
	$subject->addObject($this);
	$subject->setDom($this->{_dom});
	
	$subject->addVal('http://www.w3.org/1999/02/22-rdf-syntax-ns#type',
		Swignition::RDFModel::Value->new('http://www.holygoat.co.uk/owl/redwood/0.1/tags/Tag', 1));

	$subject->addVal('http://www.w3.org/2000/01/rdf-schema#label',
		Swignition::RDFModel::Value->new($this->{label}))
		if (length $this->{label});

	$subject->addVal('http://www.holygoat.co.uk/owl/redwood/0.1/tags/name',
		Swignition::RDFModel::Value->new($this->{tag}))
		if (length $this->{tag});

	$subject->addVal('http://bblfish.net/work/atom-owl/2006-06-06/#scheme',
		Swignition::RDFModel::Value->new($this->{tagspace}, 1))
		if (length $this->{tagspace});

	return $subject;
	
} #/sub rdf_subject


sub rdf_subject_tagging
{
	my $this    = shift;

	# Create RDF subject
	my $subject = Swignition::RDFModel::Subject->new($this->uri_tagging);
	$subject->addObject($this);
	$subject->setDom($this->{_dom});
	
	$subject->addVal('http://www.w3.org/1999/02/22-rdf-syntax-ns#type',
		Swignition::RDFModel::Value->new('http://www.holygoat.co.uk/owl/redwood/0.1/tags/Tagging', 1));

	$subject->addVal('http://www.holygoat.co.uk/owl/redwood/0.1/tags/associatedTag',
		Swignition::RDFModel::Value->new($this->uri, 1));

	return $subject;
	
} #/sub rdf_subject


sub parse
{
	my $page = shift;
	my $rv = { '_dom'=>shift };
	my $pkg = __PACKAGE__;
	if (defined $page->{uF}->{_Shortcuts}->{$pkg}->{ $rv->{_dom}->getAttribute('_xpath') })
		{ return $page->{uF}->{_Shortcuts}->{$pkg}->{ $rv->{_dom}->getAttribute('_xpath') }; }
	else
		{ $page->{uF}->{_Shortcuts}->{$pkg}->{ $rv->{_dom}->getAttribute('_xpath') } = $rv; }
	
	my $t_node = $rv->{'_dom'}->cloneNode(1);

	my $id = $t_node->getAttribute('id');
	$rv->{_id} = $id if (length $id);
	$rv->{_page} = $page;
	
	my $ts;
	my $tag = $page->uri($t_node->getAttribute('href'));
	$tag =~ s/\#.*$//;
	$tag =~ s/\?.*$//;
	$tag =~ s/\/$//;
	
	if ($tag =~ m{^(.*/)([^/]+)$})
	{
		$rv->{tagspace} = $1;
		$rv->{tag}      = ms CGI::Util::unescape($2), $t_node;
	}
	
	$rv->{href}  = $page->uri($t_node->getAttribute('href'));
	$rv->{label} = Swignition::GenericParser::Utils::STRINGIFY($t_node, 'value');
	$rv->{title} = (length $t_node->getAttribute('title'))
		? $t_node->getAttribute('title')
		: $rv->{label};
	
	bless $rv;
	return $rv;
	
} #/sub parse


sub parse_class
{
	my $page = shift;
	my $rv = { '_dom'=>shift };
	my $pkg = __PACKAGE__;
	if (defined $page->{uF}->{_Shortcuts}->{$pkg}->{ $rv->{_dom}->getAttribute('_xpath') })
		{ return $page->{uF}->{_Shortcuts}->{$pkg}->{ $rv->{_dom}->getAttribute('_xpath') }; }
	else
		{ $page->{uF}->{_Shortcuts}->{$pkg}->{ $rv->{_dom}->getAttribute('_xpath') } = $rv; }
	
	my $t_node = $rv->{'_dom'}->cloneNode(1);

	my $id = $t_node->getAttribute('id');
	$rv->{_id} = $id if (length $id);
	$rv->{_page} = $page;
	
	my $ts;
	my $tag = STRINGIFY($t_node, 'value');
	
	$rv->{tag}   = $tag;
	$rv->{href}  = 'tag:tagspace.invalid,1999-06-01:' . CGI::Util::escape($tag);	
	$rv->{label} = $tag;
	$rv->{title} = (length $t_node->getAttribute('title'))
		? $t_node->getAttribute('title')
		: $rv->{label};

	$rv->{href}  = $page->uri($t_node->getAttribute('href'))
		if ($t_node->getAttribute('href'));
		
	bless $rv;
	return $rv;
	
} #/sub parse_class


1; #/package Swignition::uF::RelTag




